package me.seu.demo.classic;

import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Guava RateLimiter是一个谷歌提供的限流工具
 * RateLimiter基于令牌桶算法，可以有效限定单个JVM实例上某个接口的流量。
 *
 * @author liangfeihu
 * @since 2020/4/16 13:58
 */
@Slf4j
public class RateLimiterExample {

    public static void main(String[] args) throws InterruptedException {
        // qps设置为5，代表一秒钟只允许处理五个并发请求
        RateLimiter rateLimiter = RateLimiter.create(5);

        ExecutorService executorService = Executors.newFixedThreadPool(5);
        int nTasks = 10;
        CountDownLatch countDownLatch = new CountDownLatch(nTasks);

        long start = System.currentTimeMillis();
        for (int i = 0; i < nTasks; i++) {
            final int j = i;
            executorService.submit(() -> {
                rateLimiter.acquire(1);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                log.info("[{}] gets job {} done", Thread.currentThread().getName(), j);
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        executorService.shutdown();

        long end = System.currentTimeMillis();
        log.info("[{}] 10 jobs gets done by 5 threads concurrently in {} milliseconds", Thread.currentThread().getName(), (end - start));
    }

}
